package com.hnchances.studentscoresystem.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hnchances.studentscoresystem.dto.request.GradesDeleteDTO;
import com.hnchances.studentscoresystem.dto.request.GradesQueryDTO;
import com.hnchances.studentscoresystem.dto.request.GradesUpdateDTO;
import com.hnchances.studentscoresystem.dto.response.GradesPageResponse;
import com.hnchances.studentscoresystem.dto.response.GradesQueryResponse;
import com.hnchances.studentscoresystem.dto.response.GradesOperateResponse;
import com.hnchances.studentscoresystem.entity.Grades;
import com.hnchances.studentscoresystem.entity.Student;
import com.hnchances.studentscoresystem.exception.BusinessException;
import com.hnchances.studentscoresystem.exception.ErrorCode;
import com.hnchances.studentscoresystem.mapper.GradesMapper;
import com.hnchances.studentscoresystem.service.GradesService;
import com.hnchances.studentscoresystem.service.StudentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 成绩管理 Service 实现类（核心业务）
 */
@Service
public class GradesServiceImpl extends BaseServiceImpl<Grades, Long, GradesMapper> implements GradesService {

    @Autowired
    private StudentService studentService;

    // ====================== 基础 CRUD 实现 ======================
    @Override
    public boolean insert(Grades grades) {
        // 补全默认值：状态默认为 0（正常）
        if (grades.getStatus() == null) {
            grades.setStatus(0);
        }
        return mapper.insert(grades) > 0;
    }

    @Override
    public Grades selectById(Long id) {
        return mapper.selectById(id);
    }

    @Override
    public List<Grades> selectAll() {
        return mapper.selectAll();
    }

    @Override
    public boolean update(Grades grades) {
        return mapper.update(grades) > 0;
    }

    @Override
    public boolean deleteById(Long id) {
        Grades grades = new Grades();
        grades.setId(id);
        grades.setStatus(1);
        return update(grades);
    }

    // ====================== 核心业务实现 ======================
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GradesOperateResponse addGrades(Grades grades, Long operatorId, Integer operatorClassId) {
        // 1. 基础参数校验
        if (grades.getCourseID() == null || grades.getExamID() == null || grades.getClassID() == null || grades.getStudentID() == null || grades.getGrades() == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "课程ID、考试ID、班级ID、学生ID、成绩不能为空");
        }
        // 成绩范围校验（0-100）
        if (grades.getGrades().compareTo(BigDecimal.ZERO) < 0 || grades.getGrades().compareTo(new BigDecimal("100")) > 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "成绩需在 0-100 范围内");
        }

        // 2. 权限校验：仅老师可新增成绩，且班级需匹配
        // （操作人身份从 Token 解析，此处简化通过参数传入，实际项目需结合 UserService 获取）
        // 假设 operatorIdentity=1（老师），此处省略身份校验，直接校验班级
        if (!operatorClassId.equals(grades.getClassID())) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED, "老师仅可登记本班级成绩");
        }

        // 3. 学生有效性校验（确保学生存在且属于当前班级）
        Student student = studentService.selectById(grades.getStudentID());
        if (student == null || student.getStatus() == 1) {
            throw new BusinessException(ErrorCode.BUSINESS_ERROR, "学生不存在或已删除");
        }
        if (!grades.getClassID().equals(student.getClassID())) {
            throw new BusinessException(ErrorCode.BUSINESS_ERROR, "学生不属于当前班级，无法登记成绩");
        }

        // 4. 新增成绩
        boolean success = insert(grades);
        GradesOperateResponse response = new GradesOperateResponse();
        response.setSuccess(success);
        response.setGradesId(grades.getId()); // 若使用自增主键，需在 Mapper 配置 useGeneratedKeys 回显 ID
        return response;
    }

    @Override
    public GradesPageResponse queryGrades(GradesQueryDTO queryDTO, Integer operatorIdentity, Integer operatorClassId) {
        // 1. 权限过滤：老师仅查本班级成绩
        if (operatorIdentity == 1) { // 1-老师
            queryDTO.setClassID(operatorClassId);
        }

        // 2. 分页参数默认值（页码默认1，每页默认10条）
        int pageNum = queryDTO.getPageNum() == null ? 1 : queryDTO.getPageNum();
        int pageSize = queryDTO.getPageSize() == null ? 10 : queryDTO.getPageSize();

        // 3. 分页查询（使用 PageHelper）
        PageHelper.startPage(pageNum, pageSize);
        List<GradesQueryResponse> gradesList = mapper.selectByCondition(queryDTO);
        PageInfo<GradesQueryResponse> pageInfo = new PageInfo<>(gradesList);

        // 4. 构建分页响应
        GradesPageResponse response = new GradesPageResponse();
        response.setPageNum(pageInfo.getPageNum());
        response.setPageSize(pageInfo.getPageSize());
        response.setTotal(pageInfo.getTotal());
        response.setGradesList(pageInfo.getList());
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GradesOperateResponse updateGrades(GradesUpdateDTO updateDTO, Long operatorId, Integer operatorClassId) {
        // 1. 查询待修改成绩
        Grades grades = selectById(updateDTO.getGradesId());
        if (grades == null || grades.getStatus() == 1) {
            throw new BusinessException(ErrorCode.BUSINESS_ERROR, "成绩不存在或已删除");
        }

        // 2. 权限校验：仅老师可修改本班级成绩
        if (!operatorClassId.equals(grades.getClassID())) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED, "老师仅可修改本班级成绩");
        }

        // 3. 成绩范围校验（若修改成绩）
        if (updateDTO.getGrades() != null) {
            if (updateDTO.getGrades().compareTo(BigDecimal.ZERO) < 0 || updateDTO.getGrades().compareTo(new BigDecimal("100")) > 0) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "成绩需在 0-100 范围内");
            }
        }

        // 4. 构建更新实体
        BeanUtils.copyProperties(updateDTO, grades, "gradesId"); // 忽略 gradesId，用原 ID
        boolean success = update(grades);

        // 5. 构建响应
        GradesOperateResponse response = new GradesOperateResponse();
        response.setSuccess(success);
        response.setGradesId(grades.getId());
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GradesOperateResponse deleteGrades(GradesDeleteDTO deleteDTO, Integer operatorIdentity, Integer operatorClassId) {
        // 1. 查询待删除成绩
        Grades grades = selectById(deleteDTO.getGradesId());
        if (grades == null || grades.getStatus() == 1) {
            throw new BusinessException(ErrorCode.BUSINESS_ERROR, "成绩不存在或已删除");
        }

        // 2. 权限校验：学生无删除权限，老师仅删本班级成绩
        if (operatorIdentity == 0) { // 0-学生
            throw new BusinessException(ErrorCode.PERMISSION_DENIED, "学生无删除成绩权限");
        } else if (operatorIdentity == 1) { // 1-老师
            if (!operatorClassId.equals(grades.getClassID())) {
                throw new BusinessException(ErrorCode.PERMISSION_DENIED, "老师仅可删除本班级成绩");
            }
        }
        // 管理员（identity=2）：无额外校验

        // 3. 软删除（修改 status 为 1）
        boolean success = deleteById(deleteDTO.getGradesId());

        // 4. 构建响应
        GradesOperateResponse response = new GradesOperateResponse();
        response.setSuccess(success);
        response.setGradesId(deleteDTO.getGradesId());
        return response;
    }
}